Vpa.Comment = function(cmtText, sourceCode, href, fileName){
    Vpa.apply(this,{
        description : "",
        tags : [],
        commentType : Vpa.Comment.commentType.NONE,
        sourceCode : sourceCode,
        sourceFileName : fileName,
        sourceHref : href,
        isPrivate : false,
        isHidden : false,
        isIgnored : false,
        isSingleton:false,
        isStatic: false
    });
    this.parseCmt(cmtText);
};

Vpa.Comment.commentType = {
    CLASS : 0,
    CLASS_INFO : 1,     //比如singleton、extends
    CONSTRUCTOR : 2,
    CFG : 3,
    EVENT : 4,
    METHOD : 5,
    PROPERTY : 6,
    NONE : 1000
};

Vpa.Comment.prototype = {
    addTag : function(tagName,text){
        var cmtType = Vpa.Comment.commentType;
        
        if(tagName == null || tagName.trim().length<1){
            return;
        }else{
            switch(tagName){
                case 'class':
                    this.tags.push(new Vpa.tag.Class(text));
                    this.commentType = cmtType.CLASS;
                    break;
                case 'singleton':
                    if(this.commentType > cmtType.CLASS_INFO)
                        this.commentType = cmtType.CLASS_INFO;
                    this.isSingleton = true;
                    break;
                case 'static':
                    this.isStatic = true;
                    break;
                case 'private':
                    this.isPrivate = true;
                    break;
                case 'ignore':
                    this.isIgnored = true;
                    break;
                case 'hidden':
                    this.isHidden = true;
                    break;
                case 'extends':
                    this.tags.push(new Vpa.tag.Extends(text));
                    if(this.commentType > cmtType.CLASS_INFO)
                        this.commentType = cmtType.CLASS_INFO;
                    break;
                case 'cfg':
                case 'config':
                    if(this.commentType > cmtType.CFG)
                        this.commentType = cmtType.CFG;
                    this.tags.push(new Vpa.tag.Cfg(text));
                    break;
                case 'constructor':
                    if(this.commentType > cmtType.CONSTRUCTOR)
                        this.commentType = cmtType.CONSTRUCTOR;
                    this.tags.push(new Vpa.tag.Constructor(text));
                    break;
                case 'event':
                    if(this.commentType > cmtType.EVENT)
                        this.commentType = cmtType.EVENT;
                    this.tags.push(new Vpa.tag.Event(text));
                    break;
                case 'member':
                    this.tags.push(new Vpa.tag.Member(text));
                    break;
                case 'method':
                    if(this.commentType > cmtType.METHOD)
                        this.commentType = cmtType.METHOD;
                    this.tags.push(new Vpa.tag.Method(text));
                    break;
                case 'param':
                    if(this.commentType > cmtType.METHOD)
                        this.commentType = cmtType.METHOD;
                    this.tags.push(new Vpa.tag.Param(text));
                    break;
                case 'return':
                    if(this.commentType > cmtType.METHOD)
                        this.commentType = cmtType.METHOD;
                    this.tags.push(new Vpa.tag.Return(text));
                    break;
                case 'property':
                    if(this.commentType > cmtType.PROPERTY)
                        this.commentType = cmtType.PROPERTY;
                    this.tags.push(new Vpa.tag.Property(text));
                    break;
                case 'type':
                    if(this.commentType > cmtType.PROPERTY)
                        this.commentType = cmtType.PROPERTY;
                    this.tags.push(new Vpa.tag.Type(text));
                    break;

            }
        }
    },
    _RegExp_Tag : new RegExp(
        '^'+
        '\\s*'+
        '@'+
        '(\\S+)'+
        '\\s*'+
        '((.|\\n)*?)'+
        '(?=' +
            '^\\s*@' +
            '|' +
            Vpa.g_str_end_tag+
        ')',

        'gm'
    ),
    _RegExp_Des : new RegExp(
        '^'+
        '(.|\n)*?'+
        '(?=' +
            '^\\s*@' +
            '|' +
            Vpa.g_str_end_tag+
        ')',

        'gm'
    ),

    parseCmt : function(cmtText){
        cmtText = cmtText
                .replace(/^\/\*\*\s*/, '')          //remove  '/**' and spaces in the beginner
                .replace(/\s*\*\/$/,'')             //remove '*/' and spaces in the end
                .replace(/^\s*\*[ \t]?(.*)/gm, '$1');  //remove stars at the start of the line

        cmtText += Vpa.g_str_end_tag;
        var description = cmtText.match(this._RegExp_Des)[0];

        if(description.trim().length>0)
            this.description = description;
        var me = this;
        cmtText.replace(
            this._RegExp_Tag,
            function(sMatch, _$1, _$2){
                me.addTag(_$1, _$2);
            }
        );

        if(me.commentType == Vpa.Comment.commentType.NONE){
            if(/^(var)?\s*\S+\s*=\s*function/.test(me.sourceCode.trim()) || /^\S+\s*:\s*function/.test(me.sourceCode.trim()))
                me.commentType = Vpa.Comment.commentType.METHOD;
        }
    },
    
    
    getTag : function(tagType){
        var tags = this.tags;
        for(var i=0,len=tags.length;i<len;i++){
            if(tags[i].tagType == tagType)
                return tags[i];
        }
        return null;
    },
    
    getTags : function(tagType){
        var tags = this.tags,
            result = [];
        for(var i=0,len=tags.length;i<len;i++){
            if(tags[i].tagType == tagType)
                result.push(tags[i]);
        }
        return result;
    }
};
